#pragma once 

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

//#define DEBUG 1

// 添加报头 "len"\n"有效载荷"\n
std::string Encode(const std::string &content){
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

// 去除报头 截取有效载荷
bool Decode(std::string &package, std::string *content){
    std::size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos){
        return false;
    }

    std::string len_str = package.substr(0, pos);
    std::size_t len = std::stoi(len_str);

    std::size_t total_len = len_str.size() + len + 2;
    if(package.size() < total_len){
        return false;
    }
    *content = package.substr(pos + 1, len);
    // 移除处理过的报文
    package.erase(0, total_len);
    
    return true;
}

class Request{
public:
    Request(const int &data1, const int &data2, const char &op)
    :_x(data1), _y(data2), _op(op)
    {}
    Request()
    {}

    bool Serialize(std::string *out){
#ifdef DEBUG
        // 序列化 构建有效载荷   "x op y"
        std::string s = std::to_string(_x);
        s += blank_space_sep;
        s += _op;
        s += blank_space_sep;
        s += std::to_string(_y);
        *out = s;
        return true;
#else
        // 创建JSON对象
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["op"] = _op;

        // 序列化
        Json::FastWriter writer;
        //Json::StyledWriter writer;
        *out = writer.write(root);
        return true;
#endif
    }

    bool Deserialize(const std::string &in){
#ifdef DEBUG
        // 反序列化 将字符串数据转换为结构化数据
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos){
            return false;
        }
        std::string part_x = in.substr(0, left);

        std::size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos){
            return false;
        }
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right){
            return false;
        }

        _op = in[left + 1];
        _x = std::stoi(part_x);
        _y = std::stoi(part_y);
        return true;
#else
        Json::Value root;
        Json::Reader reader;
        bool parse_success = reader.parse(in, root);
        if(!parse_success){
            return false;
        }
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
        return true;
#endif
    }

    void DebugPrint(){
        std::cout << "构建一个新的请求: " << _x << _op << _y << " = ?" << std::endl;
    }

    ~Request()
    {}
private:
public:
    int _x;
    int _y;
    char _op;
};


class Response{
public:
    Response(const int &result, const int &code)
    : _result(result), _code(code)
    {}
    Response()
    {}

    bool Serialize(std::string *out){
#ifdef DEBUG
        // 序列化 构建有效载荷 "result code"
        std::string s = std::to_string(_result);
        s += blank_space_sep;
        s += std::to_string(_code);
        *out = s;
        return true;
#else
        // 创建JSON对象
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        // 序列化
        Json::FastWriter writer;
        //Json::StyledWriter writer;
        *out = writer.write(root);
        return true;
#endif
    }

    bool Deserialize(const std::string &in){
#ifdef DEBUG
        // 反序列化 将字符串数据转换为结构化数据
        std::size_t pos = in.find(blank_space_sep);
        if (pos == std::string::npos){
            return false;
        }
        std::string part1 = in.substr(0, pos);
        std::string part2 = in.substr(pos + 1);
        

        _result = std::stoi(part1);
        _code = std::stoi(part2);
        return true;
#else
        // 反序列化
        Json::Value root;
        Json::Reader reader;
        bool parse_success = reader.parse(in, root);
        if (!parse_success){
            return false;
        }
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
#endif
    }

    void DebugPrint(){
        std::cout << "响应结果: " << _result <<" "<< _code << std::endl;
    }

    ~Response()
    {}
private:
public:
    int _result;
    int _code;
};